package com.base.api.service.selfOrder.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.api.dto.selfOrder.*;
import com.base.api.service.selfOrder.SelfOrderApiCommonServer;
import com.base.api.service.selfOrder.SelfOrderApiService;
import com.base.api.vo.selfOrder.*;
import com.base.exception.BaseException;
import com.base.mapper.voipmapper.SubscribersMapper;
import com.base.mapper.voipmapper.UsersConfigNewMapper;
import com.base.mapper.voipmapper.UsersMapper;
import com.base.pay.ali.AliNotifyMap;
import com.base.pay.ali.AliPayRequest;
import com.base.pay.ali.service.AliPayEasyService;
import com.base.pay.connce.ConnceResponseUtils;
import com.base.pay.wx.WxNotifyMap;
import com.base.pay.wx.WxPayRequest;
import com.base.pay.wx.service.WxPayEasyService;
import com.base.pay.wx.tool.WXPayConstants;
import com.base.pay.wx.tool.WXPayUtil;
import com.base.po.voip.Subscribers;
import com.base.po.voip.Users;
import com.base.po.voip.UsersConfigNew;
import com.base.result.PageUtils;
import com.base.result.ResponseResult;
import com.base.result.ResponseResultUtils;
import com.base.self.common.LockStockService;
import com.base.self.common.OrderGenContext;
import com.base.self.common.SelfRuntimeException;
import com.base.self.common.SelfRuntimeOkException;
import com.base.self.entity.*;
import com.base.self.enums.PtGoldbeanEnum;
import com.base.self.mapper.*;
import com.base.self.service.CommissionService;
import com.base.self.service.IPtCurrentService;
import com.base.self.service.IPtgoldbeanService;
import com.base.self.service.IPtintegralService;
import com.base.self.vos.VosRequest;
import com.base.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

@Service
@Slf4j
public class SelfOrderApiServiceImpl implements SelfOrderApiService {
    private final SelfOrderMapper selfOrderMapper;

    private final SubscribersMapper subscribersMapper;

    private final CommodityMapper commodityMapper;

    private final PtintegralMapper ptintegralMapper;

    private final WxPayEasyService wxPayEasyService;

    private final AliPayEasyService aliPayEasyService;

    private final VosRequest vosRequest;

    private final PayDealMapper payDealMapper;

    private final UsersConfigNewMapper usersConfigNewMapper;

    private final UsersMapper usersMapper;

    private final CommodityCallPlanMapper commodityCallPlanMapper;

    private final IPtCurrentService iPtCurrentService;

    private final SelfOrderApiCommonServer selfOrderApiCommonServer;

    private final LockStockService lockStockService;

    private final IPtintegralService iPtintegralService;

    private final PtgoldbeanMapper ptgoldbeanMapper;

    private final IPtgoldbeanService ptgoldbeanService;

    private final ReadWriteLock orderLock;

    private final PtSuccessMapper ptSuccessMapper;

    private final SelfDeliverMapper selfDeliverMapper;

    private final SelfCancelMapper selfCancelMapper;

    private final CommissionService CommissionService;

    @Value("${system.notify-url}")
    private String notifyUrl;

    public SelfOrderApiServiceImpl(SelfOrderMapper selfOrderMapper,
                                   SubscribersMapper subscribersMapper,
                                   CommodityMapper commodityMapper,
                                   PtintegralMapper ptintegralMapper,
                                   IPtgoldbeanService ptgoldbeanService,
                                   WxPayEasyService wxPayEasyService,
                                   AliPayEasyService aliPayEasyService,
                                   VosRequest vosRequest,
                                   PayDealMapper payDealMapper,
                                   UsersConfigNewMapper usersConfigNewMapper,
                                   UsersMapper usersMapper,
                                   CommodityCallPlanMapper commodityCallPlanMapper,
                                   IPtCurrentService iPtCurrentService,
                                   SelfOrderApiCommonServer selfOrderApiCommonServer,
                                   LockStockService lockStockService,
                                   IPtintegralService iPtintegralService,
                                   PtSuccessMapper ptSuccessMapper,
                                   SelfDeliverMapper selfDeliverMapper,
                                   SelfCancelMapper selfCancelMapper,
                                   PtgoldbeanMapper ptgoldbeanMapper,
                                   CommissionService CommissionService) {
        this.selfOrderMapper = selfOrderMapper;
        this.subscribersMapper = subscribersMapper;
        this.commodityMapper = commodityMapper;
        this.ptintegralMapper = ptintegralMapper;
        this.wxPayEasyService = wxPayEasyService;
        this.aliPayEasyService = aliPayEasyService;
        this.vosRequest = vosRequest;
        this.payDealMapper = payDealMapper;
        this.usersConfigNewMapper = usersConfigNewMapper;
        this.usersMapper = usersMapper;
        this.commodityCallPlanMapper = commodityCallPlanMapper;
        this.iPtCurrentService = iPtCurrentService;
        this.selfOrderApiCommonServer = selfOrderApiCommonServer;
        this.lockStockService = lockStockService;
        this.iPtintegralService = iPtintegralService;
        this.ptSuccessMapper = ptSuccessMapper;
        this.selfDeliverMapper = selfDeliverMapper;
        this.selfCancelMapper = selfCancelMapper;
        this.CommissionService = CommissionService;
        this.ptgoldbeanMapper = ptgoldbeanMapper;
        this.ptgoldbeanService = ptgoldbeanService;
        this.orderLock = new ReentrantReadWriteLock();
    }

    @Override
    @Transactional(noRollbackFor = {SelfRuntimeOkException.class})
    public ResponseResult partakerConfirmPayApp(HttpServletRequest request, PartakerConfirmPayAppDTO partakerConfirmPayAppDTO) throws Exception {
        selfOrderApiCommonServer.partakerOrder(partakerConfirmPayAppDTO, (selfOrder, commodity, payDeal) -> {/*支付操作*/
            setCancelOrder(selfOrder);
            appPay(request, partakerConfirmPayAppDTO.getPayWay(), selfOrder);
        }, (userId, sub1, goodsId,teamOrderNo, orderNo) -> {/*积分拼团操作*/
            if (StringUtils.isEmpty(sub1)) {
                log.warn("开团信息:用户id为{}的用户即将用订单号{},商品id为{}的信息开一个拼团",userId,orderNo,goodsId);
                iPtCurrentService.beginInTeanm(userId, goodsId, orderNo);
            } else {
                log.warn("拼团信息:用户id为{}的用户即将进入团长id:{},订单号{},商品id为{}的拼团",userId,sub1,orderNo,goodsId);
                iPtCurrentService.autoInTeam(userId, sub1, goodsId, teamOrderNo,orderNo);
            }
        });
        throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("调用支付失败"));
    }

    @Override
    @Transactional(noRollbackFor = {SelfRuntimeOkException.class})
    public ResponseResult partakerConfirmPayWap(HttpServletRequest request, PartakerConfirmPayWapDTO partakerConfirmPayWapDTO) throws Exception {
        selfOrderApiCommonServer.partakerOrder(partakerConfirmPayWapDTO, (selfOrder, commodity, payDeal) -> {/*支付操作*/
            setCancelOrder(selfOrder);
            wapPay(request, partakerConfirmPayWapDTO.getPayWay(), selfOrder);
        }, (userId, sub1, goodsId, teamOrderNo,orderNo) -> {/*积分拼团操作*/
            if (StringUtils.isEmpty(sub1)) {
                log.warn("开团信息:用户id为{}的用户即将用订单号{},商品id为{}的信息开一个拼团",userId,orderNo,goodsId);
                iPtCurrentService.beginInTeanm(userId, goodsId, orderNo);
            } else {
                log.warn("拼团信息:用户id为{}的用户即将进入团长id:{},订单号{},商品id为{}的拼团",userId,sub1,orderNo,goodsId);
                iPtCurrentService.autoInTeam(userId, sub1, goodsId, teamOrderNo, orderNo);
            }
        });
        throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("调用支付失败"));
    }

    @Override
    @Transactional(noRollbackFor = {SelfRuntimeOkException.class})
    public ResponseResult partakerConfirmPayJsapi(HttpServletRequest request, PartakerConfirmPayJsapiDTO partakerConfirmPayJsapiDTO) throws Exception {
        selfOrderApiCommonServer.partakerOrder(partakerConfirmPayJsapiDTO, (selfOrder, commodity, payDeal) -> {/*支付操作*/
            setCancelOrder(selfOrder);
            jsapiPay(request, partakerConfirmPayJsapiDTO.getOpenId(), selfOrder, payDeal);
        }, (userId, sub1, goodsId,teamOrderNo, orderNo) -> {/*积分拼团操作*/
            if (StringUtils.isEmpty(sub1)) {
                log.warn("开团信息:用户id为{}的用户即将用订单号{},商品id为{}的信息开一个拼团",userId,orderNo,goodsId);
                iPtCurrentService.beginInTeanm(userId, goodsId, orderNo);
            } else {
                log.warn("拼团信息:用户id为{}的用户即将进入团长id:{},订单号{},商品id为{}的拼团",userId,sub1,orderNo,goodsId);
                iPtCurrentService.autoInTeam(userId, sub1, goodsId, teamOrderNo,orderNo);
            }
        });
        throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("调用支付失败"));
    }

    @Override
    @Transactional(noRollbackFor = {SelfRuntimeOkException.class})
    public ResponseResult conversionConfirmPay(ConversionConfirmPayDTO conversionConfirmPayDTO) {
        final Subscribers subscribers = subscribersMapper.selectByPrimaryKey(conversionConfirmPayDTO.getUserId());
        Optional.ofNullable(subscribers).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("用户不存在")));
        final Commodity commodity = commodityMapper.selectById(conversionConfirmPayDTO.getCommodityId());
        Optional.ofNullable(commodity).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("商品信息错误")));
        final Integer stock = commodity.getCommodityStock() - conversionConfirmPayDTO.getNumber();
        if (stock.compareTo(0) < 0) {
            throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("库存不足"));
        }
        final BigDecimal sumMoney = commodity.getCommodityMarketPrice().multiply(new BigDecimal(conversionConfirmPayDTO.getNumber()));

        if (conversionConfirmPayDTO.getPayWay() != 5 ) {
            final BigDecimal userMoney = iPtintegralService.getTotalMoneyByUserId(subscribers.getId(), 0);

            if (userMoney.compareTo(sumMoney) < 0) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("有效积分不足，无法兑换。"));
            }

            ptintegralMapper.insert(selfOrderApiCommonServer.buildPtIntegral(
                    "兑换扣除",
                    subscribers.getId(),
                    0,
                    0,
                    sumMoney));
        }else {
            Integer money = ptgoldbeanMapper.userGoldbeans(subscribers.getId());
            final BigDecimal userMoney = null == money ? new BigDecimal(0):new BigDecimal(money);

            if (userMoney.compareTo(sumMoney) < 0) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("金豆不足，无法兑换。"));
            }
            Ptgoldbean ptgoldbean = new Ptgoldbean();
            ptgoldbean.setSub(subscribers.getId());
            ptgoldbean.setType(0);
            ptgoldbean.setStatus(PtGoldbeanEnum.ADD_BUY_GIFT.getStatus());
            ptgoldbean.setContext(PtGoldbeanEnum.ADD_BUY_GIFT.getContext());
            ptgoldbean.setMoney(userMoney);
            ptgoldbean.setCreateTime(new Date());
            ptgoldbeanMapper.insert(ptgoldbean);
        }
        final SelfOrder selfOrder = selfOrderApiCommonServer.buildOrder(commodity, subscribers, conversionConfirmPayDTO);
        selfOrder.setRealPrice(new BigDecimal(0));
        selfOrder.setDiscountPrice(sumMoney);
        selfOrder.setStatus(2);
        selfOrder.setIsPartaker(1);
        selfOrder.setPayTime(DateUtil.date());

        lockStockService.updateStockConversion(commodity.getId(), selfOrder.getNumber());
        selfOrderMapper.insert(selfOrder);
        return ResponseResultUtils.getResponseResultS("兑换成功");
    }

    @Override
    @Transactional(noRollbackFor = {SelfRuntimeOkException.class})
    public ResponseResult orderConfirmPayJsapi(HttpServletRequest request, OrderConfirmPayJsapiDTO orderConfirmPayJsapiDTO) throws Exception {
        selfOrderApiCommonServer.checkOrderPay(orderConfirmPayJsapiDTO, (selfOrder, payDeal) -> jsapiPay(request, orderConfirmPayJsapiDTO.getOpenId(), selfOrder, payDeal));

        throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("调用支付失败"));
    }

    @Override
    @Transactional(noRollbackFor = {SelfRuntimeOkException.class})
    public ResponseResult orderConfirmPayApp(HttpServletRequest request, OrderConfirmPayAppDTO orderConfirmPayAppDTO) throws Exception {
        selfOrderApiCommonServer.checkOrderPay(orderConfirmPayAppDTO, (selfOrder, payDeal) -> appPay(request, orderConfirmPayAppDTO.getPayWay(), selfOrder));

        throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("调用支付失败"));
    }

    @Override
    @Transactional(noRollbackFor = {SelfRuntimeOkException.class})
    public ResponseResult orderConfirmPayWap(HttpServletRequest request, OrderConfirmPayWapDTO orderConfirmPayWapDTO) throws Exception {
        selfOrderApiCommonServer.checkOrderPay(orderConfirmPayWapDTO, (selfOrder, payDeal) -> wapPay(request, orderConfirmPayWapDTO.getPayWay(), selfOrder));

        throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("调用支付失败"));
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult selfOrderSearch(SelfOrderSearchDTO selfOrderSearchDTO) {
        final Map<String, Object> data = PageUtils.getDateMapBack(() ->
                        selfOrderMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        selfOrderSearchDTO.getOffset(),
                                        selfOrderSearchDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<SelfOrder>()
                                        .eq(selfOrderSearchDTO.getStatus() != 0, SelfOrder::getStatus, selfOrderSearchDTO.getStatus())
                                        .eq(SelfOrder::getUserId, selfOrderSearchDTO.getUserId())
                                        .eq(selfOrderSearchDTO.getStatus() == 3, SelfOrder::getIsReplacement, 0)
                                        .ne(SelfOrder::getRefundStatus, 2)
                                        .eq(SelfOrder::getIsDel, 0)
                                        .orderByDesc(SelfOrder::getCreateTime)
                        )
                        ,
                        page -> {
                            List<SelfOrder> data1 = page.getRecords();
                            return data1.stream().map(x -> {
                                Long carrierId = x.getCarrierId();
                                if (carrierId != null && carrierId != 0) {/*话费礼包订单*/
                                    final CommodityCallPlan commodityCallPlan = commodityCallPlanMapper.selectById(x.getCommodityId());
                                    if (commodityCallPlan != null) {
                                        return new SelfOrderSearchVO(
                                                commodityCallPlan.getId(),
                                                commodityCallPlan.getPlanName(),
                                                commodityCallPlan.getPlanPrice(),
                                                BigDecimal.ZERO,
                                                commodityCallPlan.getPlanPic(),
                                                "",
                                                x.getNumber(),
                                                x.getOrderNo(),
                                                x.getId(),
                                                1,
                                                x.getExpressOrder(),
                                                x.getExpressStatus(),
                                                x.getExpressNumber(),
                                                x.getIsReplacement(),
                                                x.getCarrierId(),
                                                x.getRefundStatus()
                                        );
                                    }

                                } else {/*商品订单*/
                                    final Commodity commodity = commodityMapper.selectById(x.getCommodityId());
                                    if (commodity != null) {
                                        return new SelfOrderSearchVO(
                                                commodity.getId(),
                                                commodity.getCommodityName(),
                                                commodity.getCommodityRealPrice(),
                                                commodity.getCommodityMarketPrice(),
                                                commodity.getCommodityShowPic(),
                                                commodity.getCommodityStandard(),
                                                x.getNumber(),
                                                x.getOrderNo(),
                                                x.getId(),
                                                0,
                                                x.getExpressOrder(),
                                                x.getExpressStatus(),
                                                x.getExpressNumber(),
                                                x.getIsReplacement(),
                                                x.getCarrierId(),
                                                x.getRefundStatus()
                                        );
                                    }
                                }
                                return new SelfOrderSearchVO();
                            });
                        });
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    @Transactional
    public ResponseResult selfOrderDel(SelfOrderDelDTO selfOrderDelDTO) {
        final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>()
                .eq(SelfOrder::getId, selfOrderDelDTO.getOrderId())
                .eq(SelfOrder::getUserId, selfOrderDelDTO.getUserId())
        );
        Optional.ofNullable(selfOrder).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("订单信息错误")));
        selfOrder.setIsDel(1);
        selfOrder.setUpdateTime(DateUtil.date());
        selfOrderMapper.updateById(selfOrder);
        return ResponseResultUtils.getResponseResultS("删除成功");
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult selfOrderDetails(SelfOrderDetailsDTO selfOrderDetailsDTO) {
        final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>()
                .eq(SelfOrder::getId, selfOrderDetailsDTO.getOrderId())
                .eq(SelfOrder::getUserId, selfOrderDetailsDTO.getUserId())
        );
        Optional.ofNullable(selfOrder).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("订单信息错误")));

        final SelfOrderDetailsVO selfOrderDetailsVO = SelfOrderDetailsVO
                .builder()
                .commodityId(0)
                .commodityMarketPrice(BigDecimal.ZERO)
                .commodityName("")
                .commodityRealPrice(BigDecimal.ZERO)
                .commodityShowPic("")
                .commodityStandard("")
                .createTime(selfOrder.getCreateTime())
                .discountPrice(selfOrder.getDiscountPrice())
                .number(selfOrder.getNumber())
                .orderId(selfOrder.getId())
                .orderNo(selfOrder.getOrderNo())
                .payDealNo("")
                .payTime(selfOrder.getPayTime())
                .payWay(selfOrder.getPayWay())
                .realPrice(selfOrder.getRealPrice())
                .recipientsAddress(selfOrder.getRecipientsAddress())
                .recipientsMobile(selfOrder.getRecipientsMobile())
                .recipientsName(selfOrder.getRecipientsName())
                .status(selfOrder.getStatus())
                .isPartaker(selfOrder.getIsPartaker())
                .orderNumber(selfOrder.getOrderNumber())
                .isReplacement(selfOrder.getIsReplacement())
                .regimentalId(selfOrder.getRegimentalId())
                .successTime(selfOrder.getSuccessTime())
                .build();

        final Commodity commodity = commodityMapper.selectById(selfOrder.getCommodityId());
        Optional.ofNullable(commodity).ifPresent(x -> {
            selfOrderDetailsVO.setCommodityId(x.getId());
            selfOrderDetailsVO.setCommodityMarketPrice(x.getCommodityMarketPrice());
            selfOrderDetailsVO.setCommodityRealPrice(x.getCommodityRealPrice());
            selfOrderDetailsVO.setCommodityName(x.getCommodityName());
            selfOrderDetailsVO.setCommodityShowPic(x.getCommodityShowPic());
            selfOrderDetailsVO.setCommodityStandard(x.getCommodityStandard());
        });

        final PayDeal payDeal = payDealMapper.selectOne(new QueryWrapper<PayDeal>().eq("order_no", selfOrder.getOrderNo()));
        Optional.ofNullable(payDeal).ifPresent(x -> selfOrderDetailsVO.setPayDealNo(x.getPayDealNo()));

        return ResponseResultUtils.getResponseResultS("查询成功", selfOrderDetailsVO);
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult selfOrderDeckList(SelfOrderDeckListDTO selfOrderDetailsDTO) {
        final Map<String, Object> data = PageUtils.getDateMapBack(() ->
                        selfOrderMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        selfOrderDetailsDTO.getOffset(),
                                        selfOrderDetailsDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<SelfOrder>()
                                        .eq(SelfOrder::getCarrierId, 0)
                                        .eq(SelfOrder::getUserId, selfOrderDetailsDTO.getUserId())
                                        .in(SelfOrder::getStatus, 2,3,4)
                                        .eq(SelfOrder::getIsPartaker, 0)
                                        .eq(SelfOrder::getIsDel, 0)
                                        .orderByDesc(SelfOrder::getCreateTime)
                        )
                ,
                page -> {
                    List<SelfOrder> data1 = page.getRecords();
                    return data1.stream().map(x -> {
                        final Commodity commodity = commodityMapper.selectById(x.getCommodityId());
                        if (commodity != null) {
                            return new SelfOrderDeckListVO(
                                    commodity.getId(),
                                    commodity.getCommodityName(),
                                    commodity.getCommodityMarketPrice(),
                                    commodity.getCommodityRealPrice(),
                                    commodity.getCommodityShowPic(),
                                    x.getId(),
                                    x.getStatus(),
                                    x.getIsReplacement()
                            );
                        }
                        return new SelfOrderSearchVO();
                    });
                });
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    @Transactional
    public ResponseResult selfOrderReplacement(SelfOrderReplacementDTO selfOrderReplacementDTO) {
        final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>()
                .eq(SelfOrder::getId, selfOrderReplacementDTO.getOrderId())
                .eq(SelfOrder::getUserId, selfOrderReplacementDTO.getUserId())
        );
        Optional.ofNullable(selfOrder).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("订单信息错误")));
        final Commodity commodity = commodityMapper.selectById(selfOrder.getCommodityId());
        Optional.ofNullable(commodity).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("订单商品信息错误")));
        if (selfOrder.getIsReplacement() == 1) {
            return ResponseResultUtils.getResponseResultF("不能重复置换。");
        }
        if (selfOrder.getStatus() != 2) {
            return ResponseResultUtils.getResponseResultF("订单未支付或已发货,无法置换。");
        }
        String context = "置换["+ selfOrder.getOrderNo() +"]" + "所得";
        final Ptintegral ptintegral = selfOrderApiCommonServer.buildPtIntegral(context, selfOrderReplacementDTO.getUserId(), 0, 1, commodity.getCommodityMarketPrice());
        ptintegralMapper.insert(ptintegral);
        selfOrder.setIsReplacement(1);
        //selfOrder.setStatus(5);/*selfOrderSearch isReplacement = 0*/
        selfOrderMapper.updateById(selfOrder);
        return ResponseResultUtils.getResponseResultS("置换奖励金成功");
    }

    @Override
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public void partakerAliNotify(HttpServletRequest request) {
        final Map<String, String> params = AliNotifyMap.getParams(request);
        final String orderNo = params.get("out_trade_no");
        final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>().eq(SelfOrder::getOrderNo, orderNo));
        Optional.ofNullable(selfOrder).ifPresent(x -> aliPayEasyService.notify(params, this::playPartakerNotify, x.getParentId()));
    }

    @Override
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public void partakerWxNotify(HttpServletRequest request) throws Exception {
        final Map<String, String> params = WxNotifyMap.getParams(request);
        final String orderNo = params.get("out_trade_no");
        final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>().eq(SelfOrder::getOrderNo, orderNo));
        Optional.ofNullable(selfOrder).ifPresent(x -> wxPayEasyService.notify(params, this::playPartakerNotify, x.getParentId()));
    }

    //{transaction_id=4200000913202012309923676826,
    // nonce_str=CbJq46rtp3j0aYQOOi3rhQfZDTk8fmxI,
    // bank_type=GDB_CREDIT, openid=oapeJ5_bq3WHXGoZb5-i8C3OvRtU,
    // sign=C6BCDEDB458E79DBD74EFBD94D47D4F8, fee_type=CNY, mch_id=1604919232,
    // cash_fee=9191, out_trade_no=PT20123009344426010038, appid=wx2775f5e7e2db96e7,
    // total_fee=9191, trade_type=JSAPI, result_code=SUCCESS, time_end=20201230093449,
    // is_subscribe=Y, return_code=SUCCESS}
    public ResponseResult manualWxNotify() {
        Map<String, String> params = new HashMap<>();
        params.put("transaction_id", "4200000913202012309923676826");
        params.put("nonce_str", "CbJq46rtp3j0aYQOOi3rhQfZDTk8fmxI");
        params.put("bank_type", "GDB_CREDIT");
        params.put("openid", "oapeJ5_bq3WHXGoZb5-i8C3OvRtU");
        params.put("sign", "C6BCDEDB458E79DBD74EFBD94D47D4F8");
        params.put("mch_id", "1604919232");
        params.put("fee_type", "CNY");
        params.put("cash_fee", "9191");
        params.put("out_trade_no", "PT20123009344426010038");
        params.put("appid", "wx2775f5e7e2db96e7");
        params.put("total_fee", "9191");
        params.put("trade_type", "JSAPI");
        params.put("result_code", "SUCCESS");
        params.put("time_end", "20201230093449");
        params.put("is_subscribe", "Y");
        params.put("return_code", "SUCCESS");
        final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>().eq(SelfOrder::getOrderNo, "PT20123009344426010038"));
        Optional.ofNullable(selfOrder).ifPresent(x -> wxPayEasyService.notify(params, this::playPartakerNotify, x.getParentId()));
        return null;
    }

    private void playPartakerNotify(final Map<String, String> params){
        orderLock.readLock().lock();
        try {
            final String orderNo = params.get("out_trade_no");

            log.warn("订单通知处理：{}", orderNo);
            /*交易订单查询入*/
            final PayDeal payDeal = payDealMapper.selectOne(new LambdaQueryWrapper<PayDeal>()
                    .eq(PayDeal::getOrderNo, orderNo));
            /*校验金额是否一致*/
            if (payDeal.getPayWay() == 1) {
                final String totalAmount = params.get("total_amount");
                if (payDeal.getMoney().compareTo(new BigDecimal(totalAmount)) != 0) {
                    log.warn("交易订单金额不一致 {}", orderNo);
                    return;
                }
            }
            if (payDeal.getPayWay() == 2) {
                final String totalFee = params.get("total_fee");
                if (payDeal.getMoney().compareTo(new BigDecimal(totalFee).divide(new BigDecimal(100), 2, RoundingMode.HALF_DOWN)) != 0) {
                    log.warn("交易订单金额不一致 {}", orderNo);
                    return;
                }
            }
            if (payDeal.getStatus() == 0) {
                log.warn("通知处理哦");
                final Subscribers subscribers = subscribersMapper.selectByPrimaryKey(payDeal.getUserId());
                final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>().eq(SelfOrder::getOrderNo, orderNo));
                final Commodity commodity = commodityMapper.selectById(selfOrder.getCommodityId());
                final CommodityCallPlan commodityCallPlan = commodityCallPlanMapper.selectById(commodity.getCallPlan());

                lockStockService.updateStockPartaker(commodity.getId(), selfOrder);

                ptintegralMapper.insert(selfOrderApiCommonServer.buildPtIntegral(
                        "充值",
                        subscribers.getId(),
                        0,
                        1,
                        payDeal.getMoney()));

                ptintegralMapper.insert(selfOrderApiCommonServer.buildPtIntegral(
                        "参团扣除[正常]",
                        subscribers.getId(),
                        0,
                        0,
                        payDeal.getMoney()));

                selfOrderApiCommonServer.deductExpenses("参团扣除", subscribers.getId(), selfOrder.getDiscountPrice());

                if (StringUtils.isEmpty(selfOrder.getRegimental())) {
                    try {
                        iPtCurrentService.beginInTeanm(subscribers.getId(), String.valueOf(commodity.getId()), selfOrder.getOrderNo());
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.warn("创团失败");
                    }

                } else {
                    try {
                        if (StringUtils.isNull(selfOrder.getParentOrderNo())){
                            throw new BaseException(ResponseResultUtils.getResponseResultF("参团订单号不能为空!"));
                        }
                        iPtCurrentService.autoInTeam(subscribers.getId(), selfOrder.getRegimental(), String.valueOf(commodity.getId()),(String) selfOrder.getParentOrderNo(), selfOrder.getOrderNo());
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.warn("入团失败");
                    }

                }

                if (commodity.getCommoditySubarea() == 0) {
                    Optional.ofNullable(commodityCallPlan).ifPresent(x -> {
                        /*生成奖励话费订单*/
                        final BigDecimal money = payDeal.getMoney().add(payDeal.getMoney().multiply(new BigDecimal("0.1")));
                        final String carrieOrderNo = OrderGenContext.generateOrderNo();
                        log.warn("奖励话费订单 carrieOrderNo: {}", carrieOrderNo);
                        final Date date = DateUtil.date();
                        final SelfOrder selfOrderCarrie = SelfOrder
                                .builder()
                                .shopId(selfOrder.getShopId())
                                .parentId(selfOrder.getParentId())
                                .orderNo(carrieOrderNo)
                                .createTime(date)
                                .status(3)
                                .payWay(selfOrder.getPayWay())
                                .realPrice(money)
                                .mobile(subscribers.getMobile())
                                .userId(subscribers.getId())
                                .number(1)
                                .expressStatus(1)
                                .commodityId(commodityCallPlan.getId())
                                .commoditySubarea(0)
                                .isPartaker(0)
                                .isReplacement(0)
                                .payTime(date)
                                .carrierId(selfOrder.getId())
                                .remark(selfOrder.getRemark())
                                .recipientsAddress(selfOrder.getRecipientsAddress())
                                .recipientsMobile(selfOrder.getRecipientsMobile())
                                .recipientsName(selfOrder.getRecipientsName())
                                .build();
                        selfOrderMapper.insert(selfOrderCarrie);

                        /*话费订单发货信息 ==> 自动确认收货*/
                        final SelfDeliver selfDeliver = SelfDeliver
                                .builder()
                                .createTime(date)
                                .expirationTime(DateUtil.offsetDay(date, 7))
                                .orderId(selfOrder.getId())
                                .isPerform(0)
                                .isDel(0)
                                .build();
                        selfDeliverMapper.insert(selfDeliver);

                        /*奖励话费*/
                        Boolean isVos = vosRequest.partakerVos(
                                usersMapper.selectByPrimaryKey(subscribers.getParentid()),
                                subscribers,
                                selfOrder.getOrderNo(),
                                money
                        );
                        log.warn("奖励话费: {}", isVos);
                    });
                }

                selfOrder.setUpdateTime(DateUtil.date());
                selfOrder.setStatus(6);
                selfOrder.setIsPartaker(0);
                selfOrder.setPayTime(DateUtil.date());
                selfOrderMapper.updateById(selfOrder);

                /*设置交易流水号*/
                if (selfOrder.getPayWay() == 1) {
                    payDeal.setPayDealNo(params.get("trade_no"));
                }
                if (selfOrder.getPayWay() == 2) {
                    payDeal.setPayDealNo(params.get("transaction_id"));
                }

                /*取消  订单取消*/
                final SelfCancel selfCancel = selfCancelMapper.selectOne(new LambdaQueryWrapper<SelfCancel>().eq(SelfCancel::getOrderId, selfOrder.getId()));
                selfCancel.setIsPerform(1);
                selfCancelMapper.updateById(selfCancel);

                /* 一级代理/二级代理返利 */
                try {
                    CommissionService.agentCommission(
                            selfOrder.getOrderNo(),
                            selfOrder.getUserId(),
                            selfOrder.getRealPrice()
                    );
                }catch (Exception e) {
                    e.printStackTrace();
                    log.warn("一级代理/二级代理返利 返利失败 {}", selfOrder.getUserId());
                }
                /*赠送金豆*/
               ptgoldbeanService.buyGift( selfOrder.getUserId(),selfOrder.getOrderNo());


                payDeal.setStatus(1);
                payDealMapper.updateById(payDeal);
            }
        }finally {
            orderLock.readLock().unlock();
        }
    }

    @Override
    public ResponseResult partakerAliRefund(String orderNo, BigDecimal money){
        final AliPayRequest aliPayRequest = AliPayRequest.builder()
                .outTradeNo(orderNo)
                .refundAmount(AliPayRequest.ALI_DF.format(money))
                .RequestNo(IdUtil.fastSimpleUUID())
                .build();
        aliPayEasyService.refund(aliPayRequest, (map) -> log.warn(map.toString()));
        return ResponseResultUtils.getResponseResultS("退款成功");
    }

    @Override
    public ResponseResult partakerWxRefund(String orderNo, BigDecimal money){
        Map<String, String> params = new TreeMap<>();
        params.put("out_trade_no", orderNo);
        params.put("out_refund_no", IdUtil.fastSimpleUUID());
        params.put("total_fee", WxPayRequest.WX_DF.format(money.multiply(new BigDecimal(100))));
        params.put("refund_fee", WxPayRequest.WX_DF.format(money.multiply(new BigDecimal(100))));
        params.put("refund_desc", "测试退款");
        final WxPayRequest wxPayRequest = WxPayRequest.builder()
                .params(params)
                .build();
        wxPayEasyService.refund(wxPayRequest, (data) -> log.warn(data.toString()));
        return ResponseResultUtils.getResponseResultS("退款成功");
    }

    @Override
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public ResponseResult manualPartakerNotify(String data) {
        try {
            Map<String, String> map = ConnceResponseUtils.getMap(data);
            this.playPartakerNotify(map);
            return ResponseResultUtils.getResponseResultSUCCESS();
        }catch (Exception e){
            e.printStackTrace();
        }
        throw new SelfRuntimeException(ResponseResultUtils.getResponseResultFAILED());
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult latestSpelling(LatestSpellingDTO latestSpellingDTO) {
        final Map<String, Object> data = PageUtils.getDateMapBack(() ->
                        ptSuccessMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        latestSpellingDTO.getOffset(),
                                        latestSpellingDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<PtSuccess>()
                                        .select(PtSuccess::getId)
                                        .orderByDesc(PtSuccess::getCreateTime)
                        )
                ,
                page -> {
                    List<PtSuccess> data1 = page.getRecords();
                    return data1.stream().map(x -> {
                        final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>().eq(SelfOrder::getRegimentalId, x.getId()));
                        final Commodity commodity = commodityMapper.selectById(selfOrder.getCommodityId());
                        final Subscribers subscribers = subscribersMapper.selectByPrimaryKey(selfOrder.getUserId());
                        if (commodity != null && subscribers != null) {
                            return LatestSpellingVO
                                    .builder()
                                    .commodityId(commodity.getId())
                                    .commodityShowPic(commodity.getCommodityShowPic())
                                    .userMobile(StringUtils.isEmpty(subscribers.getMobile()) ? "" : subscribers.getMobile().replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"))
                                    .userName(StringUtils.isEmpty(subscribers.getUsername()) ? "" : subscribers.getUsername().replaceAll("(\\S)\\S{2,}", "$1**"))
                                    .commodityMarketPrice(commodity.getCommodityMarketPrice())
                                    .commodityRealPrice(commodity.getCommodityRealPrice())
                                    .build();
                        }
                        return LatestSpellingVO.builder().build();
                    });
                });
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult aboutSpelling(AboutSpellingDTO aboutSpellingDTO) {
        final Map<String, Object> data = PageUtils.getDateMapBack(() ->
                        selfOrderMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        aboutSpellingDTO.getOffset(),
                                        aboutSpellingDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<SelfOrder>()
                                        .select(SelfOrder::getCommodityId, SelfOrder::getUserId)
                                        .eq(SelfOrder::getStatus, 6)
                                        .eq(SelfOrder::getIsPartaker, 0)
                                        .eq(SelfOrder::getIsDel, 0)
                                        .orderByDesc(SelfOrder::getCreateTime)
                        )
                ,
                page -> {
                    List<SelfOrder> data1 = page.getRecords();
                    return data1.stream().map(x -> {
                        final Commodity commodity = commodityMapper.selectById(x.getCommodityId());
                        final Subscribers subscribers = subscribersMapper.selectByPrimaryKey(x.getUserId());
                        if (commodity != null && subscribers != null) {
                            return AboutSpellingVO
                                    .builder()
                                    .commodityId(commodity.getId())
                                    .commodityName(commodity.getCommodityName())
                                    .commodityShowPic(commodity.getCommodityShowPic())
                                    .otherness(iPtCurrentService.chaTP(subscribers.getId(), String.valueOf(x.getOrderNo())))
                                    .commodityMarketPrice(commodity.getCommodityMarketPrice())
                                    .commodityRealPrice(commodity.getCommodityRealPrice())
                                    .build();
                        }
                        return AboutSpellingVO.builder().build();
                    });
                });
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult latestSpellingViewMore(LatestSpellingViewMoreDTO latestSpellingViewMoreDTO) {
        final Map<String, Object> data = PageUtils.getDateMapBack(() ->
                        ptSuccessMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        latestSpellingViewMoreDTO.getOffset(),
                                        latestSpellingViewMoreDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<PtSuccess>()
                                        .select(
                                                PtSuccess::getId
                                        )
                                        .orderByDesc(PtSuccess::getCreateTime)
                        )
                ,
                page -> {
                    List<PtSuccess> data1 = page.getRecords();
                    return data1.stream().map(x -> {
                        final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>().eq(SelfOrder::getRegimentalId, x.getId()));
                        final Commodity commodity = commodityMapper.selectById(selfOrder.getCommodityId());
                        final Subscribers subscribers = subscribersMapper.selectByPrimaryKey(selfOrder.getUserId());
                        if (commodity != null && subscribers != null) {
                            return LatestSpellingViewMoreVO
                                    .builder()
                                    .commodityId(commodity.getId())
                                    .commodityName(commodity.getCommodityName())
                                    .commodityShowPic(commodity.getCommodityShowPic())
                                    .orderNumber(selfOrder.getOrderNumber())
                                    .userMobile(StringUtils.isEmpty(subscribers.getMobile()) ? "" : subscribers.getMobile().replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"))
                                    .userName(StringUtils.isEmpty(subscribers.getUsername()) ? "" : subscribers.getUsername().replaceAll("(\\S)\\S{2,}", "$1**"))
                                    .successTime(selfOrder.getSuccessTime())
                                    .commodityMarketPrice(commodity.getCommodityMarketPrice())
                                    .commodityRealPrice(commodity.getCommodityRealPrice())
                                    .build();
                        }
                        return LatestSpellingViewMoreVO.builder().build();
                    });
                });
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult partakerRecord(PartakerRecordDTO partakerRecordDTO) {
        final Map<String, Object> data = PageUtils.getDateMapBack(() ->
                        selfOrderMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        partakerRecordDTO.getOffset(),
                                        partakerRecordDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<SelfOrder>()
                                        .select(
                                                SelfOrder::getCommodityId, SelfOrder::getUserId
                                        )
                                        .eq(SelfOrder::getUserId, partakerRecordDTO.getUserId())
                                        .eq(SelfOrder::getIsPartaker, 0)
                                        .eq(SelfOrder::getIsDel, 0)
                                        .orderByDesc(SelfOrder::getCreateTime)
                        )
                ,
                page -> {
                    List<SelfOrder> data1 = page.getRecords();
                    return data1.stream().map(x -> {
                        final Commodity commodity = commodityMapper.selectById(x.getCommodityId());
                        if (commodity != null) {
                            return PartakerRecordVO
                                    .builder()
                                    .orderId(x.getId())
                                    .commodityId(commodity.getId())
                                    .commodityName(commodity.getCommodityName())
                                    .commodityShowPic(commodity.getCommodityShowPic())
                                    .commodityMarketPrice(commodity.getCommodityMarketPrice())
                                    .commodityRealPrice(commodity.getCommodityRealPrice())
                                    .build();
                        }
                        return PartakerRecordVO.builder().build();
                    });
                });
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult conversionRecord(ConversionRecordDTO conversionRecordDTO) {
        final Map<String, Object> data = PageUtils.getDateMapBack(() ->
                        selfOrderMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        conversionRecordDTO.getOffset(),
                                        conversionRecordDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<SelfOrder>()
                                        .select(
                                                SelfOrder::getCommodityId, SelfOrder::getUserId
                                        )
                                        .eq(SelfOrder::getUserId, conversionRecordDTO.getUserId())
                                        .eq(SelfOrder::getIsPartaker, 1)
                                        .eq(SelfOrder::getIsDel, 0)
                                        .orderByDesc(SelfOrder::getCreateTime)
                        )
                ,
                page -> {
                    List<SelfOrder> data1 = page.getRecords();
                    return data1.stream().map(x -> {
                        final Commodity commodity = commodityMapper.selectById(x.getCommodityId());
                        if (commodity != null) {
                            return ConversionRecordVO
                                    .builder()
                                    .orderId(x.getId())
                                    .commodityId(commodity.getId())
                                    .commodityName(commodity.getCommodityName())
                                    .commodityShowPic(commodity.getCommodityShowPic())
                                    .commodityMarketPrice(commodity.getCommodityMarketPrice())
                                    .commodityRealPrice(commodity.getCommodityRealPrice())
                                    .build();
                        }
                        return ConversionRecordVO.builder().build();
                    });
                });
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    public ResponseResult commodityConversionRecord(CommodityConversionRecordDTO commodityConversionRecordDTO) {
        final Map<String, Object> data = PageUtils.getDateMapBack(() ->
                        selfOrderMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        commodityConversionRecordDTO.getOffset(),
                                        commodityConversionRecordDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<SelfOrder>()
                                        .select(
                                                SelfOrder::getCommodityId, SelfOrder::getUserId
                                        )
                                        .eq(SelfOrder::getCommodityId, commodityConversionRecordDTO.getCommodityId())
                                        .eq(SelfOrder::getIsPartaker, 1)
                                        .eq(SelfOrder::getIsDel, 0)
                                        .orderByDesc(SelfOrder::getCreateTime)
                        )
                ,
                page -> {
                    List<SelfOrder> data1 = page.getRecords();
                    return data1.stream().map(x -> {
                        final Commodity commodity = commodityMapper.selectById(x.getCommodityId());
                        if (commodity != null) {
                            return CommodityConversionRecordVO
                                    .builder()
                                    .orderId(x.getId())
                                    .commodityId(commodity.getId())
                                    .commodityName(commodity.getCommodityName())
                                    .commodityShowPic(commodity.getCommodityShowPic())
                                    .createTime(x.getCreateTime())
                                    .build();
                        }
                        return CommodityConversionRecordVO.builder().build();
                    });
                });
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    @Transactional
    public ResponseResult confirmReceipt(ConfirmReceiptDTO confirmReceiptDTO) {
        final SelfOrder selfOrder = selfOrderMapper.selectOne(new LambdaQueryWrapper<SelfOrder>()
                .eq(SelfOrder::getId, confirmReceiptDTO.getOrderId())
                .eq(SelfOrder::getUserId, confirmReceiptDTO.getUserId())
        );
        Optional.ofNullable(selfOrder).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("订单信息错误")));

        if (selfOrder.getStatus() != 3) {
            return ResponseResultUtils.getResponseResultF("订单状态信息错误或未发货");
        }
        selfOrder.setStatus(4);
        selfOrderMapper.updateById(selfOrder);

        /*更新自动收货信息*/
        final SelfDeliver selfDeliver = selfDeliverMapper.selectOne(new LambdaQueryWrapper<SelfDeliver>().eq(SelfDeliver::getOrderId, selfOrder.getId()));
        Optional.ofNullable(selfDeliver).ifPresent(x -> {
            x.setIsPerform(1);
            selfDeliverMapper.updateById(x);
        });
        return ResponseResultUtils.getResponseResultS("确认收货成功");
    }

    private void jsapiPay(final HttpServletRequest request, final String openId, final SelfOrder selfOrder, final PayDeal payDeal) throws Exception {
        final Map<String, String> params = WxNotifyMap.getRequestMap(request,
                "拼团",
                selfOrder.getOrderNo(),
                selfOrder.getRealPrice(),
                notifyUrl + "api/selfOrder/partakerWxNotify");
        params.put("trade_type", "JSAPI");
        params.put("openid", openId);
        log.warn("微信jsapi支付：{}", params);
        final WxPayRequest wxPayRequest = WxPayRequest.builder()
                .params(params)
                .parentId(selfOrder.getParentId())
                .build();
        Map<String, String> map = wxPayEasyService.jsPay(wxPayRequest);
        log.warn("微信jsapi返回：{}", map);
        if (map.get("return_code").equals("FAIL")) {
            throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF(map.get("return_msg")));
        }
        if (map.get("result_code").equals("FAIL")) {
            throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF(map.get("err_code_des")));
        }
        throw new SelfRuntimeOkException(ResponseResultUtils.getResponseResultS(
                "调用微信成功",
                transferJs(usersMapper.selectByPrimaryKey(payDeal.getParentId()), map))
        );
    }

    private void wapPay(final HttpServletRequest request, final Integer payWay, final SelfOrder selfOrder){
        if (payWay == 1) {
            final AliPayRequest aliPayRequest = AliPayRequest.builder()
                    .outTradeNo(selfOrder.getOrderNo())
                    .asyncNotify(notifyUrl + "api/selfOrder/partakerAliNotify")
                    .totalAmount(AliPayRequest.ALI_DF.format(selfOrder.getRealPrice()))
                    .quitUrl("")
                    .returnUrl(AliPayRequest.RETURN_URL)
                    .subject("拼团")
                    .parentId(selfOrder.getParentId())
                    .build();
            Map<String, Object> map = aliPayEasyService.wapPay(aliPayRequest);
            if (CollectionUtils.isEmpty(map)) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("调用支付宝失败"));
            }
            throw new SelfRuntimeOkException(ResponseResultUtils.getResponseResultS(
                    "调用支付宝成功",
                    map.get("body")
            ));
        }

        if (payWay == 2) {
            Map<String, Object> wap = new HashMap<>();
            Map<String, Object> type = new HashMap<>();
            type.put("wap_url", ""/*WAP网站URL地址*/);
            type.put("wap_name", ""/*WAP 网站名*/);
            wap.put("h5_info", "h5_info");
            wap.put("type", type);
            final Map<String, String> params = WxNotifyMap.getRequestMap(request,
                    "拼团",
                    selfOrder.getOrderNo(),
                    selfOrder.getRealPrice(),
                    notifyUrl + "api/selfOrder/partakerWxNotify");
            params.put("trade_type", "MWEB");
            params.put("scene_info", JSON.toJSONString(wap));
            final WxPayRequest wxPayRequest = WxPayRequest.builder()
                    .params(params)
                    .parentId(selfOrder.getParentId())
                    .build();
            Map<String, String> map = wxPayEasyService.wapPay(wxPayRequest);
            log.warn("微信wap返回：{}", map);
            if (map.get("return_code").equals("FAIL")) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF(map.get("return_msg")));
            }
            if (map.get("result_code").equals("FAIL")) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF(map.get("err_code_des")));
            }
            throw new SelfRuntimeOkException(ResponseResultUtils.getResponseResultS("调用微信成功", map));
        }
    }

    private void appPay(final HttpServletRequest request, final Integer payWay, final SelfOrder selfOrder) throws Exception {
        if (payWay == 1) {
            final AliPayRequest aliPayRequest = AliPayRequest.builder()
                    .outTradeNo(selfOrder.getOrderNo())
                    .asyncNotify(notifyUrl + "api/selfOrder/partakerAliNotify")
                    .totalAmount(AliPayRequest.ALI_DF.format(selfOrder.getRealPrice()))
                    .subject("拼团")
                    .parentId(selfOrder.getParentId())
                    .build();
            Map<String, Object> map = aliPayEasyService.appPay(aliPayRequest);
            log.warn("支付宝app返回：{}", map);
            if (CollectionUtils.isEmpty(map)) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("调用支付宝失败"));
            }
            throw new SelfRuntimeOkException(ResponseResultUtils.getResponseResultS(
                    "调用支付宝成功",
                    map.get("body")
            ));
        }

        if (payWay == 2) {
            final Map<String, String> params = WxNotifyMap.getRequestMap(request,
                    "拼团",
                    selfOrder.getOrderNo(),
                    selfOrder.getRealPrice(),
                    notifyUrl + "api/selfOrder/partakerWxNotify");
            params.put("trade_type", "APP");
            final WxPayRequest wxPayRequest = WxPayRequest.builder()
                    .params(params)
                    .parentId(selfOrder.getParentId())
                    .build();
            Map<String, String> map = wxPayEasyService.wapPay(wxPayRequest);
            log.warn("微信app返回：{}", map);
            if (map.get("return_code").equals("FAIL")) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF(map.get("return_msg")));
            }
            if (map.get("result_code").equals("FAIL")) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF(map.get("err_code_des")));
            }
            throw new SelfRuntimeOkException(ResponseResultUtils.getResponseResultS(
                    "调用微信成功",
                    transferApp(usersMapper.selectByPrimaryKey(selfOrder.getParentId()), map)
            ));
        }
    }

    private void setCancelOrder(final SelfOrder selfOrder){
        Date date = DateUtil.date();
        final SelfCancel selfCancel = SelfCancel
                .builder()
                .createTime(date)
                .expirationTime(DateUtil.offsetMinute(date, 30))
                .isDel(0)
                .isPerform(0)
                .orderId(selfOrder.getId())
                .build();
        selfCancelMapper.insert(selfCancel);
    }

    private Map<String, String> transferJs(Users users, Map<String, String> map) throws Exception {
        final UsersConfigNew usersConfigNew = usersConfigNewMapper.selectByParentId(users.getId());
        Map<String, String> param = new TreeMap<>();
        param.put("appId", usersConfigNew.getWxMpAppid() == null ? "" : usersConfigNew.getWxMpAppid());
        param.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
        param.put("nonceStr", map.get("nonce_str"));
        param.put("package", "prepay_id=" + map.get("prepay_id"));
        param.put("signType", WXPayConstants.MD5);
        param.put("sign", WXPayUtil.generateSignature(param, users.getWxapikey() == null ? "" : users.getWxapikey(), WXPayConstants.SignType.MD5));
        log.warn("微信支付调起jsapi支付参数：【{}】", param);
        return param;
    }

    private Map<String, String> transferApp(Users users, Map<String, String> map) throws Exception {
        Map<String, String> param = new TreeMap<>();
        param.put("appid", users.getWxappid() == null ? "" : users.getWxappid());
        param.put("partnerid", users.getWxmchid() == null ? "" : users.getWxmchid());
        param.put("timestamp", Long.toString((System.currentTimeMillis() / 1000)));
        param.put("noncestr", map.get("nonce_str"));
        param.put("prepayid", map.get("prepay_id"));
        param.put("package", "Sign=WXPay");
        String sign2 = WXPayUtil.generateSignature(param, users.getWxapikey() == null ? "" : users.getWxapikey(), WXPayConstants.SignType.MD5);
        param.put("sign", sign2);
        log.warn("微信支付调起APP支付参数：【{}】", param);
        return param;
    }
}
